/*
 * Copyright 2002-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.security.config.annotation.web.configurers

import io.terminus.lego.shinda.web.security.phone.filter.SMSCodeAuthenticationProcessingFilter
import io.terminus.lego.shinda.web.security.phone.provider.SmsAuthenticationProvider
import org.springframework.security.config.annotation.web.HttpSecurityBuilder
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
import org.springframework.security.web.util.matcher.RequestMatcher

/**
 *
 */
class SmsLoginConfigurer<H : HttpSecurityBuilder<H>> constructor(filter: SMSCodeAuthenticationProcessingFilter,
                                                                 val provider: SmsAuthenticationProvider) :
        AbstractAuthenticationFilterConfigurer<H, SmsLoginConfigurer<H>, SMSCodeAuthenticationProcessingFilter>(filter, null) {
    /**
     * Creates a new instance
     * @see HttpSecurity.formLogin
     */
    init {
        phoneParameter("phoneNumber")
        codeParameter("verificationCode")
    }

    /**
     *
     */
    public override fun loginPage(loginPage: String): SmsLoginConfigurer<H> {
        return super.loginPage(loginPage)
    }

    /**
     * The HTTP parameter to look for the username when performing authentication. Default
     * is "username".

     * @param phoneParameter the HTTP parameter to look for the username when
     * * performing authentication
     * *
     * @return the [SmsLoginConfigurer] for additional customization
     */
    fun phoneParameter(phoneParameter: String): SmsLoginConfigurer<H> {
        authenticationFilter.PARAMTER_KEY_CODE = phoneParameter
        return this
    }

    /**
     * The HTTP parameter to look for the password when performing authentication. Default
     * is "password".

     * @param codeParameter the HTTP parameter to look for the password when
     * * performing authentication
     * *
     * @return the [SmsLoginConfigurer] for additional customization
     */
    fun codeParameter(codeParameter: String): SmsLoginConfigurer<H> {
        authenticationFilter.PARAMTER_KEY_CODE = codeParameter
        return this
    }

    /**
     * Forward Authentication Failure Handler

     * @param forwardUrl the target URL in case of failure
     * *
     * @return the [SmsLoginConfigurer] for additional customization
     */
    fun failureForwardUrl(forwardUrl: String): SmsLoginConfigurer<H> {
        failureHandler(ForwardAuthenticationFailureHandler(forwardUrl))
        return this
    }

    /**
     * Forward Authentication Success Handler

     * @param forwardUrl the target URL in case of success
     * *
     * @return the [SmsLoginConfigurer] for additional customization
     */
    fun successForwardUrl(forwardUrl: String): SmsLoginConfigurer<H> {
        successHandler(ForwardAuthenticationSuccessHandler(forwardUrl))
        return this
    }

    @Throws(Exception::class)
    override fun init(http: H) {
        super.init(http)
        http.authenticationProvider(provider)
    }

    /*
	 * (non-Javadoc)
	 *
	 * @see org.springframework.security.config.annotation.web.configurers.
	 * AbstractAuthenticationFilterConfigurer
	 * #createLoginProcessingUrlMatcher(java.lang.String)
	 */
    override fun createLoginProcessingUrlMatcher(loginProcessingUrl: String): RequestMatcher {
        return AntPathRequestMatcher(loginProcessingUrl, "POST")
    }

    /**
     * Gets the HTTP parameter that is used to submit the username.

     * @return the HTTP parameter that is used to submit the username
     */
    private val phoneParameter: String
        get() = authenticationFilter.PARAMTER_KEY_PHONE

    /**
     * Gets the HTTP parameter that is used to submit the password.

     * @return the HTTP parameter that is used to submit the password
     */
    private val codeParameter: String
        get() = authenticationFilter.PARAMTER_KEY_CODE


}
